﻿/**	@file		lolix_macro.h
 *	@date		(2005-12-09 23:28:37)/(2011-04-28 21:16:42)
 *-----------------------------------------------------------------------------
 *	\brief			常用的一些宏定义.
 *	@version	1.0.54.79
 *	@author		Nick Shallery	(nicknide@gmail.com)
 *	@copyright	YOU HAVE ALL LEFT WITH THIS CODE WHILE YOU KEEP COMMENT IN EVERY COPY.
 *-----------------------------------------------------------------------------
**/


#if			!defined(__LOLIX__LOLI_X_MACRO__K_IN_G__)
#define		__LOLIX__LOLI_X_MACRO__K_IN_G__

#if			!defined(__LOLIX__LOLI_X_CFG__K_IN_G__)
	#include	"./lolix_cfg.h"
#endif	//	!defined(__LOLIX__LOLI_X_CFG__K_IN_G__)


#if			LOLIX_CFG__REDEF_LOLIX_DEF_MACRO	>	0
	#define		LOLIX_ASSERT			LOLIX_DEF__LOLIX_ASSERT
	#define		LOLIX_IS_ERROR			LOLIX_DEF__LOLIX_IS_ERROR
	#define		LOLIX_IS_WARNING		LOLIX_DEF__LOLIX_IS_WARNING
	#define		LOLIX_CHECK_ERROR		LOLIX_DEF__LOLIX_CHECK_ERROR
	#define		LOLIX_RETURN_ERROR		LOLIX_DEF__LOLIX_RETURN_ERROR
	#define		LOLIX_ASSERT_EX			LOLIX_DEF__LOLIX_ASSERT_EX
	#define		LOLIX_TRACE				LOLIX_DEF__TRACE
	#define		LOLIX_TRACE_HERE		LOLIX_DEF__TRACE_HERE
	#define		PART_U8_OF				LOLIX_DEF__PART_U8_OF
	#define		PART_U16_OF				LOLIX_DEF__PART_U16_OF
	#define		PART_U32_OF				LOLIX_DEF__PART_U32_OF
	#define		LOLIX_ETYPE				LOLIX_DEF__ETYPE
#endif	//	LOLIX_CFG__REDEF_LOLIX_DEF_MACRO	>	0

#if			LOLIX_CFG__REDEF_LOLIX_DEF_MACRO	>	2
	#define		CANNT_COPY_LOLI			LOLIX_DEF__CANNT_COPY_LOLI
	#define		SYS_REGIST_TYPE_BEGIN	LOLIX_DEF__SYS_REGIST_TYPE_BEGIN
	#define		SYS_REGIST_TYPE_END		LOLIX_DEF__SYS_REGIST_TYPE_END
#endif	//	LOLIX_CFG__REDEF_LOLIX_DEF_MACRO	>	2

#if			LOLIX_CFG__REDEF_LOLIX_DEF_MACRO	>	4
	#define		TRACE_HERE				LOLIX_DEF__TRACE_HERE
	#define		LINK_SYMBOL				LOLIX_DEF__LINK_SYMBOL
	#define		SHOW_INFO				LOLIX_DEF__SHOW_INFO
	#define		SHOW_WARNING			LOLIX_DEF__SHOW_WARNING
	#define		SHOW_ERROR				LOLIX_DEF__SHOW_ERROR
#endif	//	LOLIX_CFG__REDEF_LOLIX_DEF_MACRO	>	4

#if			LOLIX_CFG__REDEF_LOLIX_DEF_MACRO	>	6
	#define		STATIC_ASSERT			LOLIX_DEF__STATIC_ASSERT
#endif	//	LOLIX_CFG__REDEF_LOLIX_DEF_MACRO	>	6

#if			LOLIX_CFG__REDEF_LOLIX_DEF_MACRO	>	8
	#undef		ASSERT
	#define		ASSERT		LOLIX_ASSERT

	#undef		assert
	#define		assert		LOLIX_ASSERT

	#undef		TRACE
	#define		TRACE		LOLIX_DEF__TRACE
#endif	//	LOLIX_CFG__REDEF_LOLIX_DEF_MACRO	>	8


#define		LOLIX_RANDOM_NAME_WITH_(name)	LOLIX_DEF__LINK_SYMBOL(name, __COUNTER__)

#if			defined(LOLIX_DEF__CC_TYPE_MS)
	#define		__PUSH_AND_DISABLE_WARNING(id)	__pragma (warning(push))__pragma (warning(disable : id))
	#define		__POP_WARNING()					__pragma (warning(pop))
#else	//	defined(LOLIX_DEF__CC_TYPE_MS)
	#define		__PUSH_AND_DISABLE_WARNING(id)
	#define		__POP_WARNING()
#endif	//	defined(LOLIX_DEF__CC_TYPE_MS)

#define		__BEGIN_DISABLE_CONSTANT_CONDITIONAL_EXPRESSION_WARNING()	__PUSH_AND_DISABLE_WARNING(4127)
#define		__END_DISABLE_CONSTANT_CONDITIONAL_EXPRESSION_WARNING()		__POP_WARNING()
#define		__BEGIN_DISABLE_NO_NAME_STRUCT_WARNING()					__PUSH_AND_DISABLE_WARNING(4201)
#define		__END_DISABLE_NO_NAME_STRUCT_WARNING()						__POP_WARNING()
//#define		__BEGIN_DISABLE_CONVERSION_FROM_SIZE_T_TO_OTHER()			__PUSH_AND_DISABLE_WARNING(4267)
//#define		__END_DISABLE_CONVERSION_FROM_SIZE_T_TO_OTHER()				__POP_WARNING()

#define		__LOLIX__BEGIN_MACRO()			do{
#define		__LOLIX__END_MACRO()			}__BEGIN_DISABLE_CONSTANT_CONDITIONAL_EXPRESSION_WARNING()while(0) __END_DISABLE_CONSTANT_CONDITIONAL_EXPRESSION_WARNING()

#define		LOLIX_DEF__ENTER_SECTION()		__LOLIX__BEGIN_MACRO()
#define		LOLIX_DEF__LEAVE_SECTION()		__LOLIX__END_MACRO()

#define		NULL_OPT						__LOLIX__BEGIN_MACRO() __LOLIX__END_MACRO()
#if			defined(__cplusplus)

#define	nake_invoke(para1, para2)					__nake_invoke__0__(para1, para2, __COUNTER__)
#define	__nake_invoke__0__(para1, para2, li)		__nake_invoke__1__(para1, para2, LOLIX_DEF__LINK_SYMBOL(__nake_invoke_type__, li), LOLIX_DEF__LINK_SYMBOL(__nake_invoke_obj_, li))
#define	__nake_invoke__1__(para1, para2, type_name, obj_name)	\
	class type_name									\
	{												\
	public:											\
		type_name(void){para1;}						\
		~type_name(void){para2;}					\
	}obj_name


#define	bind_invoke(obj, para1, para2)			pair_invoke(decltype((obj)), para1, para2, (obj))
#define	pair_invoke(type, para1, para2, obj)	pair_invoke_0(type, (_obj).para1, (_obj).para2, (obj), __COUNTER__)
#define	atexit_invoke(obj, para)				pair_invoke_0(decltype(obj), ;, (_obj).para, (obj), __COUNTER__)
#define	atexit_release(obj)						atexit_invoke(obj, release())

#define pair_invoke_0(type, para1, para2, obj, li)	pair_invoke_1(type, para1, para2, obj, LOLIX_DEF__LINK_SYMBOL(pair_invoke_type_, li), LOLIX_DEF__LINK_SYMBOL(pair_invoke_class_, li), LOLIX_DEF__LINK_SYMBOL(pair_invoke_obj_, li))
#define pair_invoke_1(type, para1, para2, obj, tname, cname, oname)	\
	typedef type	tname;											\
	class cname														\
	{																\
	public:															\
		LOLIX_INLINE_CALL cname(tname& robj):_obj(robj){para1;}		\
		LOLIX_INLINE_CALL ~cname(void){para2;}						\
	private:														\
		void operator = (const cname&){}							\
		tname& _obj;												\
	}oname(obj)

#define		LXUT_DEF__QUERY_ITF_WITH_ERROR_RT(lx_inst, type, name)	\
	type* name;\
	do{\
		const lolix::LOLIX_ITF_ID tmp_itf_id = LOLIX_ITF_FROM_VAL(*name);\
		if ( LOLIX_IS_ERROR(rtv = lx_inst->query_itf((lolix::itf**)&name, &tmp_itf_id)) )\
			return rtv;\
		atexit_invoke(*name, release());\
	}while(0)

#endif	/*	defined(__cplusplus)	*/


/*>>------------------------------------------------------------------------*/

#if			LOLIX_CFG__IS_DEBUG
	#define		LOLIX_DEF__TRACE			lolix::toy::lx_assert::lolix_trace_class::get_trace_class().lolix_trace
	#define		LOLIX_DEF__TRACE_POSITION	LOLIX_DEF__TRACE("%s", SHOW_WHERE)
	#define		LOLIX_DEF__TRACE_HERE		LOLIX_DEF__TRACE_POSITION.lolix_trace(L":").lolix_trace
#else	/*	LOLIX_CFG__IS_DEBUG	*/
	#define		LOLIX_DEF__TRACE			__BEGIN_DISABLE_CONSTANT_CONDITIONAL_EXPRESSION_WARNING()if(0)__END_DISABLE_CONSTANT_CONDITIONAL_EXPRESSION_WARNING()
	#define		LOLIX_DEF__TRACE_POSITION	LOLIX_DEF__TRACE
	#define		LOLIX_DEF__TRACE_HERE		LOLIX_DEF__TRACE
#endif	/*	LOLIX_CFG__IS_DEBUG	*/

#define	SHOW_WHERE				__FILE__"("__INT_TO_STR__(__LINE__)")"


#if			LOLIX_CFG__CC_SHOW_MSG_LEVEL >= 2
	#define	LOLIX_DEF__SHOW_INFO	LOLIX_DEF__SHOW_ERROR

#else	//	LOLIX_CFG__CC_SHOW_MSG_LEVEL > 2
	#define	LOLIX_DEF__SHOW_INFO(msg)

#endif	//	LOLIX_CFG__CC_SHOW_MSG_LEVEL > 2

#if			LOLIX_CFG__CC_SHOW_MSG_LEVEL >= 1
	#define	LOLIX_DEF__SHOW_WARNING	LOLIX_DEF__SHOW_ERROR

#else	//	LOLIX_CFG__CC_SHOW_MSG_LEVEL >= 1
	#define	LOLIX_DEF__SHOW_WARNING(msg)

#endif	//	LOLIX_CFG__CC_SHOW_MSG_LEVEL >= 1

#define	LOLIX_DEF__SHOW_ERROR(msg)	__pragma(message(SHOW_WHERE" : " msg))


#define	DSHOW_MSG(msg)				__pragma(message(SHOW_WHERE" : " msg))
#define	SHOW_MSG					DSHOW_MSG
/*>>------------------------------------------------------------------------*/

#define	LOLIX_ASSERT_VOID(val)						LOLIX_ASSERT(val, #val)
#if			LOLIX_CFG__IS_DEBUG
	#define	DO_IN_DEBUG_MODEL(some)		__BEGIN_DISABLE_CONSTANT_CONDITIONAL_EXPRESSION_WARNING()do{some;}while(0)__END_DISABLE_CONSTANT_CONDITIONAL_EXPRESSION_WARNING()
	#define	DO_IN_DEBUG_MODEL_WITH_COMMA(some)		, some
	#define	DO_IN_RELASE_MODEL(some)	NULL_OPT
	#define	LOLIX_DEF__DEBUG_CODE
	#define	LOLIX_DEF__RELEASE_CODE		/##/


#else	/*	LOLIX_CFG__IS_DEBUG	*/
	#define	DO_IN_DEBUG_MODEL(some)					NULL_OPT
	#define	DO_IN_DEBUG_MODEL_WITH_COMMA(some)
	#define	DO_IN_RELASE_MODEL(some)	__BEGIN_DISABLE_CONSTANT_CONDITIONAL_EXPRESSION_WARNING()do{some;}while(0)__END_DISABLE_CONSTANT_CONDITIONAL_EXPRESSION_WARNING()
	#define	LOLIX_DEF__DEBUG_CODE		__LINK_SYMBOL_STRING__(/,/)
	#define	LOLIX_DEF__RELEASE_CODE

#endif	/*	LOLIX_CFG__IS_DEBUG	*/

#if			!defined(_MSC_VER)
#undef	NULL_OPT
#define	NULL_OPT	do{}while(0)
#endif	//	!defined(_MSC_VER)
/*>>------------------------------------------------------------------------*/


#define		__LINK_SYMBOL_STRING__(a,b)		a##b
#define		LOLIX_DEF__LINK_SYMBOL(a,b)			__LINK_SYMBOL_STRING__(a,b)
#define		__LINK_SYMBOL3__(a,b,c)			LOLIX_DEF__LINK_SYMBOL(LOLIX_DEF__LINK_SYMBOL(a,b), c)
#define		__INT_TO_STR_BASE__(symbol)		#symbol
#define		__INT_TO_STR__(symbol)			__INT_TO_STR_BASE__(symbol)


#define		PTR_2_VAL(ptr)				( (char*)(ptr) - (char*)0 )
#define		VAL_2_PTR(val)				( (char*)0 + (val))

#define		LOLIX_DEF__PART_U8_OF(val, pos)		(((val)>>(8*(pos)))&0xff)
#define		LOLIX_DEF__PART_U16_OF(val, pos)	(((val)>>(16*(pos)))&0xffff)
#define		LOLIX_DEF__PART_U32_OF(val, pos)	(((val)>>(32*(pos)))&0xffffffff)

#define		PTR_TO_VAL(vtype, ptr)		(vtype)PTR_2_VAL(ptr)
#define		VAL_TO_PTR(ptype, val)		(ptype)VAL_2_PTR(val)

namespace lolix{namespace _help{
template<typename T, unsigned long long size>
char (*__check_array_func( T (&) [size] ))[size];
}}

#define		ARRAY_SIZE(array)			sizeof(*lolix::_help::__check_array_func(array))
#define		ARRAY_TAIL(array)			((array)[ARRAY_SIZE(array)-1])
#define		ARRAY_BEGIN(array)			(array)
#define		ARRAY_END(array)			((array)+ARRAY_SIZE(array))
#define		CAST_PTR(type,ptr)			(static_cast<type*>(ptr))

#if			defined(STATIC_CAST)
	#undef	STATIC_CAST
#endif	//	defined(STATIC_CAST)

#define		STATIC_CAST(dec, src)		(static_cast<::lolix::remove_reference<decltype(dec)>::type>(src))

#if			defined(STATIC_COPY)
	#undef	STATIC_COPY
#endif	//	defined(STATIC_COPY)


#define		__LOLIX_XMODE_COPY(dec, src, mod)	__BEGIN_DISABLE_CONSTANT_CONDITIONAL_EXPRESSION_WARNING()do{dec = mod((dec), (src));}while(0)__END_DISABLE_CONSTANT_CONDITIONAL_EXPRESSION_WARNING()

#define		STATIC_COPY(dec,src)		__LOLIX_XMODE_COPY(dec, src, STATIC_CAST)

#define		CONST_CAST(dec, src)		(const_cast<::lolix::remove_reference<decltype(dec)>::type>(src))
#define		CONST_COPY(dec, src)		__LOLIX_XMODE_COPY(dec, src, CONST_CAST)

#define		REINTERPRET_CAST(dec, src)	(reinterpret_cast<decltype(dec)>(src))
#define		REINTERPRET_COPY(dec, src)	__LOLIX_XMODE_COPY(dec, src, REINTERPRET_CAST)

#define		DYNAMIC_CAST(dec, src)		(dynamic_cast<decltype(dec)>(src))
#define		DYNAMIC_COPY(dec, src)		__LOLIX_XMODE_COPY(dec, src, DYNAMIC_CAST)


/*------------------------------------
//End Def Some person define
/---------------------------------------------*/


/*-----------------------------------------------
//Second: the Size of Basic Data Type
/------------------------------------*/
#if			defined(KB) || defined (GB) || defined(MB) || defined (TB)
#	error		Re Defined Here
#endif

#define		TB(large)	(((unsigned long long)large)*(1<<40))
#define		GB(large)	(((unsigned long long)large)*(1<<30))
#define		MB(large)	(((unsigned long long)large)*(1<<20))
#define		KB(large)	((large)*(1<<10))


#if			defined(_MSC_VER)
	#if			_MSC_VER < 1400
		#define		__LOLIX_DEPRECATED(str)	__declspec(deprecated)
	#else	/*	_MSC_VER < 1400	*/
		#define		__LOLIX_DEPRECATED(str)	__declspec(deprecated(str))
	#endif	/*	_MSC_VER < 1400	*/

		#define		LOLIX_NO_VTABLE	__declspec(novtable)

#else	/*	defined(_MSC_VER)	*/
		#define		__LOLIX_DEPRECATED(str)
		#define		LOLIX_NO_VTABLE
#endif	/*	defined(_MSC_VER)	*/


#if			LOLIX_CFG__THROWS_EXCEPT
	#define	__LOLIX_BEGIN_TRY__							try{
	#define	__LOLIX_THROW__(no_throw_opt, throw_opt)	(throw_opt)
	#define	__LOLIX_CATCH_ALL__							}catch(...){
	#define	__LOLIX_RAISE__								throw;
	#define	__LOLIX_END_TRY__							}
#else	//	LOLIX_CFG__THROWS_EXCEPT
	#define	__LOLIX_BEGIN_TRY__							__BEGIN_DISABLE_CONSTANT_CONDITIONAL_EXPRESSION_WARNING()if(1){__END_DISABLE_CONSTANT_CONDITIONAL_EXPRESSION_WARNING()
	#define	__LOLIX_THROW__(no_throw_opt, throw_opt)	no_throw_opt
	#define	__LOLIX_CATCH_ALL__							}__BEGIN_DISABLE_CONSTANT_CONDITIONAL_EXPRESSION_WARNING()if(0)__END_DISABLE_CONSTANT_CONDITIONAL_EXPRESSION_WARNING(){
	#define	__LOLIX_RAISE__								NULL_OPT;
	#define	__LOLIX_END_TRY__							}
#endif	//	LOLIX_CFG__THROWS_EXCEPT

#if			defined(LOLIX_CFG__PLATFORM_TYPE_WINDOWS) || LOLIX_CFG__SIZE_TYPE_BITS_SIZE == 32
	#define		LOLIX_STD_CALL		__stdcall
#else	//	defined(LOLIX_CFG__PLATFORM_TYPE_WINDOWS) || LOLIX_CFG__SIZE_TYPE_BITS_SIZE == 32
	#define		LOLIX_STD_CALL
#endif	//	defined(LOLIX_CFG__PLATFORM_TYPE_WINDOWS) || LOLIX_CFG__SIZE_TYPE_BITS_SIZE == 32

#define		LOLIX_CALL			LOLIX_CALL_THROWS
#define		LOLIX_CALL_THROWS	LOLIX_STD_CALL

#if			LOLIX_CFG__THROWS_EXCEPT
	#define	LOLIX_INLINE_CALL	inline
#else	//	LOLIX_CFG__THROWS_EXCEPT
	#define	LOLIX_INLINE_CALL	inline __declspec(nothrow)
#endif	//	LOLIX_CFG__THROWS_EXCEPT


#if			LOLIX_CFG__CC_WARNING_FOR_DEPRECATED
#define		LOLIX_DEF__DEPRECATED(info)	__LOLIX_DEPRECATED("deprecated:" info)
#else	//	LOLIX_CFG__CC_WARNING_FOR_DEPRECATED
#define		LOLIX_DEF__DEPRECATED(info)
#endif	//	LOLIX_CFG__CC_WARNING_FOR_DEPRECATED

#if			LOLIX_CFG__CC_WARNING_FOR_NO_STANDARD
#define		LOLIX_WARNING_FOR_NO_STANDARD(info)	__LOLIX_DEPRECATED("standardless warning:" info)
#else	//	LOLIX_CFG__CC_WARNING_FOR_NO_STANDARD
#define		LOLIX_WARNING_FOR_NO_STANDARD(info)
#endif	//	LOLIX_CFG__CC_WARNING_FOR_NO_STANDARD

#if			LOLIX_CFG__CC_WARNING_FOR_PERFORMANCE
#define		LOLIX_WARNING_FOR_PERFORMANCE(info)	__LOLIX_DEPRECATED("performance warning:" info)
#else	//	LOLIX_CFG__CC_WARNING_FOR_PERFORMANCE
#define		LOLIX_WARNING_FOR_PERFORMANCE(info)
#endif	//	LOLIX_CFG__CC_WARNING_FOR_PERFORMANCE


#define		LOLIX_INTERFACE(name, rtv, param)				LOLIX_INTERFACE_DEFINE(name, rtv, param) = 0
#define		LOLIX_INTERFACE_DEFINE							LOLIX_INTERFACE_DEF
#define		LOLIX_INTERFACE_DEF(name, rtv, param)		virtual	rtv	LOLIX_CALL	name	param
#define		LOLIX_INTERFACE_DEPRECATED(name, rtv, param, info)	LOLIX_DEF__DEPRECATED(info) LOLIX_INTERFACE(name, rtv, param)
#define		__LOLIX_INTERFACE	LOLIX_INTERFACE

#define		LOLIX_DEF__ZERO_ITF_ID	0, 0, 0, 0

#if			LOLIX_CFG__CRITICAL_SECTION_MARK_TIME
	#define		LOLIX_CS_MARK_NAME(name)		name
	#define		LOLIX_CS_MARK_NAME_P(name)		, name
	#define		LOLIX_CS_MARK_NAME_CHOISE(need_do, no_do)	need_do
	#define		LOLIX_CS_DEFINE_NAME(name)	name

#else	//	LOLIX_CFG__CRITICAL_SECTION_MARK_TIME
	#define		LOLIX_CS_MARK_NAME(name)
	#define		LOLIX_CS_MARK_NAME_P(name)
	#define		LOLIX_CS_MARK_NAME_CHOISE(need_do, no_do)	no_do
	#define		LOLIX_CS_DEFINE_NAME(name)	0

#endif	//	LOLIX_CFG__CRITICAL_SECTION_MARK_TIME

#define		LOLIX_CS_MARK_NAME_CHOISE_P(need_do, no_do)	, LOLIX_CS_MARK_NAME_CHOISE(no_do, need_do)

#define		LOLIX_OFFSET_OF(s,m)   (lolix::size_type)(&reinterpret_cast<const volatile char&>((((s *)0)->m)))

#define		FILL_BITS(type, from, end)	( ((type)1<<(end)) - ((type)1<<(from)) )

#endif	//	!defined(__LOLIX__LOLI_X_MACRO__K_IN_G__)
